package com.yeyks.service.impl;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.yeyks.exception.ServiceException;
import com.yeyks.model.em.ResponseStatus;
import com.yeyks.service.TokenService;
import com.yeyks.exception.ServiceException;
import com.yeyks.model.em.ResponseStatus;
import com.yeyks.service.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author fuchangshuai
 * @date 2019/3/26 3:18 PM
 */
@Slf4j
@Service
public class TokenServiceImpl implements TokenService {
    /**
     * token秘钥
     */
    private static final String SECRET = "269e2643-b259-419c-bc4d-23b34d09f9f4";
    /**
     * token 过期时间: 10天
     */
    private static final int calendarField = Calendar.DATE;
    private static final int calendarInterval = 100;

    /**
     * 由当前用户ID创建对应Token，有效期为10天（calendarInterval * calendarField)
     *
     * @param userId
     * @return
     */
    public String createToken(String userId) {
        Date iatDate = new Date();
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(calendarField, calendarInterval);
        Date expiresDate = nowTime.getTime();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("alg", "HMAC256");
        map.put("type", "JWT");
        return JWT.create().withHeader(map) // header
                .withClaim("userId", userId)
                .withIssuedAt(iatDate) // sign time
                .withExpiresAt(expiresDate) // expire time
                .sign(Algorithm.HMAC256(SECRET));

    }

    /**
     * 解密Token，获得内容
     *
     * @param token
     * @return
     */
    private static Map<String, Claim> getClaims(String token) {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT jwt = verifier.verify(token);
        return jwt.getClaims();
    }

    /**
     * 根据Token获取user_id
     *
     * @param token
     * @return user_id
     */
    public String getUserId(String token) {
        String userId;
        try {
            Map<String, Claim> claims = getClaims(token);
            Claim user_id_claim = claims.get("userId");
            userId = user_id_claim == null ? null : user_id_claim.asString();
        } catch (Throwable e) {
            log.error("无效的token{}", e.getLocalizedMessage());
            throw new ServiceException("无效的token");
        }
        if (userId == null) {
            log.info("token过期，请重新登陆，token={}", token);
            throw new ServiceException(ResponseStatus.RS_FAIL_INVALID_TOKEN.getCode(), "用户信息失效，请重新登陆");
        }
        return userId;
    }
}
